# main.py
import sys
import logging
import json
import asyncio
import argparse
from typing import Dict, Any, List
from src.core.graph_manager import GraphManager
from src.tools.jira_connector import JiraConnector
from src.tools.mcp_client import create_mcp_connection, MCPClient  # 移除未使用的send_mcp_message
from langchain_core.messages import HumanMessage, BaseMessage  # 明确导入消息基类
from config import config

# 配置日志，增加文件名和行号信息
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s'
)
logger = logging.getLogger(__name__)

async def test_mcp_connection() -> None:
    """测试MCP服务器连接并列出可用工具"""
    print("\n" + "="*50)
    print("Testing MCP Server Connection")
    print("="*50)
    
    try:
        # 获取MCP配置
        server_url = config.mcp_url
        api_key = config.mcp_api_key
        
        if not server_url:
            raise ValueError("MCP server URL is not configured in config")
        
        # 创建MCP连接
        connector: MCPClient = await create_mcp_connection(
            server_url=server_url,
            api_key=api_key
        )
        
        # 测试连接和工具列表
        print(f"\n1. Testing connection initialization to {server_url}...")
        tools_result: List[Dict[str, Any]] = await connector.list_tools()
        print("   Available tools:", json.dumps(tools_result, indent=2, ensure_ascii=False))
        
        print("\n" + "="*50)
        print("MCP Connection Test Completed Successfully")
        print("="*50)
        
    except Exception as e:
        logger.error(f"MCP connection test failed: {str(e)}", exc_info=True)
        print(f"\nTest Failed: {str(e)}")
    finally:
        # 确保连接关闭
        if 'connector' in locals():
            try:
                await connector.close()
            except Exception as close_err:
                logger.warning(f"Error closing MCP connection: {str(close_err)}")
async def run_web_server() -> None:
    """异步启动FastAPI服务器，修复包检查逻辑"""
    try:
        # 明确检查fastapi和uvicorn是否均可导入
        import fastapi
        import uvicorn
        from src.api.app import app  # 确保api.app能正确导入（依赖fastapi）
        
        # 打印版本信息，确认导入成功
        logger.info(f"FastAPI version: {fastapi.__version__}")
        logger.info(f"Uvicorn version: {uvicorn.__version__}")
        logger.info("Starting web server on http://0.0.0.0:8000")
        
        # 启动服务器
        config = uvicorn.Config(
            app=app,
            host="0.0.0.0",
            port=8000,
            log_level="info"
        )
        server = uvicorn.Server(config)
        await server.serve()
        
    except ImportError as e:
        # 精确判断是哪个包未导入
        missing_pkg = str(e).split("'")[1]  # 提取缺失的包名
        error_msg = f"Missing required package: {missing_pkg}. Please install with: pip install {missing_pkg}"
        logger.error(error_msg)
        print(f"Error: {error_msg}")
    except Exception as e:
        logger.error(f"Web server failed to start: {str(e)}", exc_info=True)
        print(f"\nWeb Server Error: {str(e)}")
async def main() -> None:
    """应用程序主入口"""
    parser = argparse.ArgumentParser(description="Agentic Jira Conference System")
    parser.add_argument("--test-mcp", action="store_true", help="Test MCP server connection")
    parser.add_argument("--web", action="store_true", help="Run as web server")
    args = parser.parse_args()
    
    # 处理Web服务器模式
    if args.web:
        await run_web_server()
        return
    
    logger.info("Starting Agentic Jira Conference System")
    
    # 处理MCP测试模式
    if args.test_mcp:
        await test_mcp_connection()
        return
    
    # 初始化代理图
    try:
        graph_manager = GraphManager()
        graph = graph_manager.compile()
        logger.info("Agent graph initialized successfully")
    except Exception as e:
        logger.error(f"Failed to initialize agent graph: {str(e)}", exc_info=True)
        print(f"Error initializing system: {str(e)}")
        return
    
    # 命令行交互提示
    print("Agentic Jira Conference System")
    print("Type 'exit' or 'quit' to end the conversation")
    print("Type 'test-mcp' to test MCP server connection")
    print("-" * 40)
    
    # 交互循环
    while True:
        try:
            user_input = input("\nYou: ").strip()
            
            # 处理退出命令
            if user_input.lower() in ['exit', 'quit']:
                logger.info("User requested exit")
                print("Goodbye!")
                break
            
            # 处理MCP测试命令
            if user_input.lower() == 'test-mcp':
                await test_mcp_connection()
                continue
                
            # 忽略空输入
            if not user_input:
                continue
            
            logger.info(f"Processing user input: {user_input}")
            
            # 准备输入数据
            inputs: Dict[str, Any] = {
                "messages": [HumanMessage(content=user_input)],
                "next": "",
                "rag_needed": False,
                "rag_response": "",
                "tool_response": "",
                "agent_action": "",
                "agent_response": "",
                "current_agent": ""
            }
            
            # 异步处理输入（使用LangChain的异步调用方法）
            logger.info("Invoking agent graph")
            result = await graph.ainvoke(inputs)  # 改为异步调用
            logger.info("Agent graph processing completed")
            
            # 提取并显示响应
            messages: List[BaseMessage] = result.get("messages", [])
            if messages and isinstance(messages, list):
                last_msg = messages[-1]
                if isinstance(last_msg, BaseMessage) and hasattr(last_msg, 'content'):
                    final_response = last_msg.content
                    logger.info(f"Agent response generated: {final_response[:100]}...")  # 截断长日志
                    print(f"\nAgent: {final_response}")
                else:
                    logger.warning(f"Last message is not a valid BaseMessage: {type(last_msg)}")
                    print("\nAgent: Received invalid response format.")
            else:
                logger.warning("No messages returned from agent graph")
                print("\nAgent: No response generated.")
            
        except KeyboardInterrupt:
            logger.info("Keyboard interrupt received")
            print("\n\nGoodbye!")
            break
        except Exception as e:
            logger.error(f"Error in interaction loop: {str(e)}", exc_info=True)
            print(f"\nError: {str(e)}. Please try again.")

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except Exception as e:
        logger.critical(f"Application crashed: {str(e)}", exc_info=True)
        sys.exit(1)